package hall

import (
	"context"
	"io"
	"net/http"
)

type Handler[Req any, Resp any] interface {
	ReqDecoder(ctx context.Context, reader io.Reader, req *Req) error
	RespEncoder(ctx context.Context, resp Resp, writer io.Writer) error
	Handle(ctx context.Context, req Req, resp *Resp)
}

type HandlerFunc[Req any, Resp any] func(ctx context.Context, req Req, resp *Resp)

type FuncHandler[Req any, Resp any] struct {
	HandlerFunc HandlerFunc[Req, Resp]
	Decoder     ReqDecoder[Req]
	Encoder     RespEncoder[Resp]
}

const RequestKey = "Request"
const UserParamsKey = "UserParams"

type UserParams struct {
	params map[string]string
}

type ReqDecoder[Req any] func(ctx context.Context, reader io.Reader, req *Req) error
type RespEncoder[Resp any] func(ctx context.Context, resp Resp, writer io.Writer) error

type JsonResult struct {
	Code     int         `json:"code"`
	ErrorMsg string      `json:"errorMsg,omitempty"`
	Data     interface{} `json:"data"`
}

const MethodGet = http.MethodGet
const MethodPost = http.MethodPost
const MethodPut = http.MethodPut
const MethodPatch = http.MethodPatch
const MethodDelete = http.MethodDelete
const MethodOptions = http.MethodOptions
const MethodHead = http.MethodHead
const MethodConnect = http.MethodConnect
const MethodTrace = http.MethodTrace

const StatusMovedPermanently = http.StatusMovedPermanently
const StatusPermanentRedirect = http.StatusPermanentRedirect
